using System;
using System.Collections.Generic;
using System.Text;
using System.Drawing;
using System.Windows.Forms;
using System.Diagnostics;

namespace GoodStuff
{
     public class GoodRectangleControl : GoodControlGroupBox
     {
         GoodNumericVariable<int>[] _variables;
         GoodNumericUpDown[] _controls;
         bool _updating;
         public GoodRectangleControl()
         {
             Trace.WriteLine("GoodRectangleControl constructor called");
             _controls = new GoodNumericUpDown[4];
             _variables = new GoodNumericVariable<int>[4];
             Margin = new Padding(Margin.Left, 15, Margin.Right, Margin.Bottom);
         }

         // called when the rectangle is updated from outside or during a U/I update with _updating = true;
         protected override void OnVariableChanged(object sender, EventArgs args)
         {
             if (!_updating)
             {
                _updating = true;
                Rectangle r = (_variable as GoodVariable<Rectangle>).Value;
                 _variables[0].Value = r.X;
                 _variables[1].Value = r.Width;
                 _variables[2].Value = r.Y;
                 _variables[3].Value = r.Height;
                 _updating = false;
              }
         }

         // called when one of the GoodNumericUpDowns changes
         public void OnControlChanged(object sender, EventArgs args)
         {
             Trace.WriteLine("GoodRectangle " + _variable.Name + " changed in UI");

             if (!_updating)
             {
                 _updating = true;
                 Rectangle newRectangle = new Rectangle(
                     (int)_variables[0].Value,
                     (int)_variables[2].Value,
                     (int)_variables[1].Value,
                     (int)_variables[3].Value);

                 (_variable as GoodVariable<Rectangle>).Value = newRectangle;

                 // check to see if the valeu of the variable changed after validation
                 Rectangle r = (_variable as GoodVariable<Rectangle>).Value;
                 if (r != newRectangle)
                 {
                     _variables[0].Value = r.X;
                     _variables[2].Value = r.Left;
                     _variables[1].Value = r.Y;
                     _variables[3].Value = r.Right;
                 }

                 _updating = false;
             }
         }


         public override void Initialize()
         {
             Trace.WriteLine("Initializing GoodRectangleControl " + _variable.Name);
             if (!(_variable is GoodVariable<Rectangle>))
                 throw (new Exception("GoodRectangle variable must have GoodVariable<Rectangle> binding"));

             base.Initialize();
             for (int i = 0; i < 4; ++i)
             {
                 _controls[i] = new GoodNumericUpDown();
                 _variables[i] = new GoodNumericVariable<int>();
             }

             _variables[0].DisplayName = "X";
             _variables[1].DisplayName = "Width";
             _variables[2].DisplayName = "Y";
             _variables[3].DisplayName = "Height";
             _variables[0].Name = "X";
             _variables[1].Name = "Width";
             _variables[2].Name = "Y";
             _variables[3].Name = "Height";

             for (int i = 0; i < 4; ++i)
             {
                 _variables[i].ValueChanged += OnControlChanged;
                 _controls[i].GoodVariableBinding = _variables[i];
                 _controls[i].Initialize();
                Controls.Add(_controls[i]);
             }

             _updating = true;
             _variables[0].Value = (_variable as GoodVariable<Rectangle>).Value.X;
             _variables[1].Value = (_variable as GoodVariable<Rectangle>).Value.Width;
             _variables[2].Value = (_variable as GoodVariable<Rectangle>).Value.Y;
             _variables[3].Value = (_variable as GoodVariable<Rectangle>).Value.Height;
             _updating = false;
             
             Size t = new Size(0, 0);
             int w = Margin.Left + Math.Max(_controls[0].Size.Width, _controls[2].Size.Width);
             int h = Margin.Top + Math.Max(_controls[0].Size.Height, _controls[1].Size.Height);
             _controls[0].Location = new Point(Margin.Left, Margin.Top);
             _controls[1].Location = new Point(
                 w + Math.Max(0, _controls[3].Width -_controls[1].Width), 
                 Margin.Top);
             _controls[2].Location = new Point(Margin.Left, h);
             _controls[3].Location = new Point(
                 w + Math.Max(0, _controls[1].Width - _controls[3].Width),  
                 h);
             w += Math.Max(_controls[1].Size.Width, _controls[3].Size.Width) + Margin.Right;
             h +=  Math.Max(_controls[2].Size.Height, _controls[3].Size.Height) + Margin.Bottom;
             Size = new Size(w, h);
             Text = _variable.DisplayName;
         }
     }

}
